﻿using System;
using Socium.Science;

namespace Socium.Documents.Sociograms {
	abstract class DragState {
		public abstract DragState BeginDrag(Vector pivot, Vector cursor);
		public abstract DragState EndDrag();

		public abstract Vector DoDrag(Vector cursor);

		protected void InvalidOperation() {
			throw new InvalidOperationException();
		}

		public static DragState Inactive() {
			return InactiveDragState.Instance;
		}

		#region ActiveDragState

		class ActiveDragState : DragState {
			readonly Vector _delta;

			public ActiveDragState(Vector pivot, Vector cursor) {
				_delta = pivot - cursor;
			}

			public override DragState BeginDrag(Vector pivot, Vector cursor) {
				InvalidOperation();
				return null;
			}

			public override DragState EndDrag() {
				return InactiveDragState.Instance;
			}

			public override Vector DoDrag(Vector cursor) {
				return cursor + _delta;
			}
		}

		#endregion

		#region InactiveDragState

		class InactiveDragState : DragState {
			public override DragState BeginDrag(Vector pivot, Vector cursor) {
				return new ActiveDragState(pivot, cursor);
			}

			public override DragState EndDrag() {
				InvalidOperation();
				return null;
			}

			public override Vector DoDrag(Vector cursor) {
				InvalidOperation();
				return Vector.Origin;
			}

			static readonly Lazy<InactiveDragState> _instance =
				new Lazy<InactiveDragState>(() => new InactiveDragState());

			public static InactiveDragState Instance {
				get { return _instance.Value; }
			}
		}

		#endregion

	}
}
